From c22bd0a9c3acbf97cf3a6dc49f06bd23fbe19923 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Sun, 14 Aug 2005 20:07:30 +0000 Subject: [PATCH] refactoring and cleanup --- ChangeLog | 16 ++++ babl/babl-classes.h | 50 ++++------ babl/babl-conversion.h | 1 + babl/babl-db.h | 2 +- babl/babl-fish.c | 193 +++++++++++++++++++++++++++++++++++---- babl/babl-fish.h | 6 +- babl/babl-format.c | 60 +++++++----- babl/babl-instance.h | 31 +++++++ babl/babl-internal.h | 3 +- babl/babl-pixel-format.c | 60 +++++++----- babl/babl.c | 1 + 11 files changed, 324 insertions(+), 99 deletions(-) create mode 100644 babl/babl-instance.h diff --git a/ChangeLog b/ChangeLog index 62e5170..e9ecb72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2005-08-14 Øyvind Kolås + + * babl/Makefile.am: added babl-instance.h, removed wilcard from + EXTRA_DIST + * babl/babl-classes.h: added BablModel **model to BablPixelFormat, + renamed BablReferenceFish to BablFishReference. Moved some logic out + to babl-instance.h. + * babl/babl-instance.h: new file. + * babl/babl-db.h: include babl-instance instead of babl-classes to + reduce amount of headers included by headers. + * babl/babl-fish.c: Added code to make it work for type conversions + * babl/babl-fish.h: Added babl_fish (source, destination) prototype + * babl/babl-internal.h: reindentation, include babl-conversion.h + * babl/babl-pixel-format.c: add model for each band + * babl/babl.c: destroy all fishes at finish + 2005-08-14 Øyvind Kolås * babl/babl-base/Makefile.am: LDADD = -lm diff --git a/babl/babl-classes.h b/babl/babl-classes.h index 6d69ea3..4055fc9 100644 --- a/babl/babl-classes.h +++ b/babl/babl-classes.h @@ -46,9 +46,15 @@ typedef void (*BablFuncPlanarBit) (int src_bands, int dst_bit_pitch[], int n); +/* magic number used at the start of all babl objects, used to do + * differentiation in polymorphic functions. (as well as manual + * type check assertions). + */ +#define BABL_MAGIC 0xbAb10000 + typedef enum { - BABL_INSTANCE = 0xBAB10000, - BABL_TYPE, + BABL_INSTANCE = BABL_MAGIC, + BABL_TYPE, BABL_SAMPLING, BABL_COMPONENT, BABL_MODEL, @@ -165,6 +171,7 @@ typedef struct BablConversion **to; /*< NULL terminated list of conversions to class */ int planar; int bands; + BablModel **model; BablComponent **component; BablType **type; BablSampling **sampling; @@ -190,11 +197,14 @@ typedef struct typedef struct { BablFish fish; + BablConversion **from; /*< these are here for a later stage, when calculated*/ + BablConversion **to; /*< reference conversions can be used for "segment" */ + /*< conversions where no other conversions exist. */ BablConversion *type_to_double; BablConversion *model_to_rgba; BablConversion *rgba_to_model; BablConversion *double_to_type; -} BablReferenceFish; +} BablFishReference; typedef union { @@ -207,39 +217,17 @@ typedef union BablPixelFormat pixel_format; BablConversion conversion; BablFish fish; - BablReferenceFish reference_fish; + BablFishReference reference_fish; BablImage image; } Babl; -#define BABL_IS_BABL(obj)\ -(NULL==(obj)?0:BABL_CLASS_TYPE_IS_VALID(((Babl*)(obj))->class_type)) - -typedef int (*BablEachFunction) (Babl *entry, - void *data); - -const char *babl_class_name (BablClassType klass); - - - -#define BABL_DEFINE_CLASS(TypeName, type_name) \ - \ -void type_name##_init (void); \ -void type_name##_destroy (void); \ -void type_name##_each (BablEachFunction each_fun, \ - void *user_data); \ -TypeName * type_name (const char *name); \ -TypeName * type_name##_id (int id); \ -TypeName * type_name##_new (const char *name, \ - ...); - +#define BABL_IS_BABL(obj) \ +(NULL==(obj)?0: \ + BABL_CLASS_TYPE_IS_VALID(((Babl*)(obj))->class_type) \ +) -#define BABL_DEFINE_CLASS_NO_NEW_NO_ID(TypeName, type_name) \ - \ -void type_name##_init (void); \ -void type_name##_destroy (void); \ -void type_name##_each (BablEachFunction each_fun, \ - void *user_data); +#include "babl-instance.h" #endif diff --git a/babl/babl-conversion.h b/babl/babl-conversion.h index 064e593..214fde0 100644 --- a/babl/babl-conversion.h +++ b/babl/babl-conversion.h @@ -21,6 +21,7 @@ #define BABL_CONVERSION_H #include "babl-classes.h" + BABL_DEFINE_CLASS(BablConversion, babl_conversion) #endif diff --git a/babl/babl-db.h b/babl/babl-db.h index 204a5bb..8b20181 100644 --- a/babl/babl-db.h +++ b/babl/babl-db.h @@ -25,7 +25,7 @@ #error babl-internal.h must be included before babl-db.h, babl-db.h is strictly internal to babl core classes. #endif -#include "babl-classes.h" +#include "babl-instance.h" #include diff --git a/babl/babl-fish.c b/babl/babl-fish.c index e4be9d8..938e8c2 100644 --- a/babl/babl-fish.c +++ b/babl/babl-fish.c @@ -23,6 +23,9 @@ #include #include +#include "babl-type.h" +#include "babl-model.h" + static int each_babl_fish_destroy (Babl *babl, void *data) @@ -32,29 +35,28 @@ each_babl_fish_destroy (Babl *babl, } BablFish * -babl_fish_new (const char *name, - Babl *source, - Babl *destination) +babl_fish_new (Babl *source, + Babl *destination) { - Babl *self = NULL; + Babl *babl = NULL; assert (BABL_IS_BABL (source)); assert (BABL_IS_BABL (destination)); - self = babl_calloc (sizeof (BablFish), 1); - self->class_type = BABL_FISH; - self->instance.id = 0; - self->instance.name = "Fishy"; - self->fish.source = (union Babl*)source; - self->fish.destination = (union Babl*)destination; + babl = babl_calloc (sizeof (BablFish), 1); + babl->class_type = BABL_FISH; + babl->instance.id = 0; + babl->instance.name = "Fishy"; + babl->fish.source = (union Babl*)source; + babl->fish.destination = (union Babl*)destination; - if (db_insert (self) == self) + if (db_insert (babl) == babl) { - return (BablFish*)self; + return (BablFish*)babl; } else { - each_babl_fish_destroy (self, NULL); + each_babl_fish_destroy (babl, NULL); return NULL; } @@ -64,10 +66,167 @@ babl_fish_new (const char *name, * is a possibility , or even full single line serialization of * components with types. * - babl_add_ptr_to_list ((void ***)&(source->type.from), self); - babl_add_ptr_to_list ((void ***)&(destination->type.to), self); + babl_add_ptr_to_list ((void ***)&(source->type.from), babl); + babl_add_ptr_to_list ((void ***)&(destination->type.to), babl); */ - return (BablFish*)self; + return (BablFish*)babl; +} + +typedef struct SearchData +{ + Babl *source; + Babl *destination; + BablConversion *result; +} SearchData; + +static int +find_conversion (Babl *babl, + void *user_data) +{ + SearchData *sd = user_data; + + if ((Babl*)babl->conversion.source == sd->source && + (Babl*)babl->conversion.destination == sd->destination) + { + sd->result = (BablConversion*)babl; + return 1; + } + return 0; +} + +BablConversion *babl_conversion_find (Babl *source, + Babl *destination) +{ + SearchData data; + data.source = source; + data.destination = destination; + data.result = NULL; + babl_conversion_each (find_conversion, &data); + + if (!data.result) + { + babl_log ("%s('%s', '%s'): failed", __FUNCTION__, + source->instance.name, destination->instance.name); + return NULL; + } + return data.result; +} + +BablFish * +babl_fish_reference_new (Babl *source, + Babl *destination) +{ + Babl *babl = NULL; + + assert (BABL_IS_BABL (source)); + assert (BABL_IS_BABL (destination)); + + babl = babl_calloc (sizeof (BablFishReference), 1); + babl->class_type = BABL_FISH_REFERENCE; + babl->instance.id = 0; + babl->instance.name = "Fishy"; + babl->fish.source = (union Babl*)source; + babl->fish.destination = (union Babl*)destination; + + babl->reference_fish.type_to_double = + babl_conversion_find ( + (Babl*)source->pixel_format.type[0], + (Babl*)babl_type_id (BABL_DOUBLE) + ); + + babl->reference_fish.model_to_rgba = + babl_conversion_find ( + (Babl*)source->pixel_format.model[0], + (Babl*)babl_model_id (BABL_RGBA) + ); + + babl->reference_fish.rgba_to_model = + babl_conversion_find ( + (Babl*)babl_model_id (BABL_RGBA), + (Babl*)destination->pixel_format.model[0] + ); + + babl->reference_fish.double_to_type = + babl_conversion_find ( + (Babl*)babl_type_id (BABL_DOUBLE), + (Babl*)destination->pixel_format.type[0] + ); + + if (db_insert (babl) == babl) + { + return (BablFish*)babl; + } + else + { + each_babl_fish_destroy (babl, NULL); + return NULL; + } + +/* Might make sense to allow a precalculated shortcut to + * participate in later checks for optimal conversions, then we + * should also have better generated names,. model + datatype + * is a possibility , or even full single line serialization of + * components with types. + + babl_add_ptr_to_list ((void ***)&(source->type.from), babl); + babl_add_ptr_to_list ((void ***)&(destination->type.to), babl); + */ + return (BablFish*) babl; +} + +BablFish * +babl_fish (Babl *source, + Babl *destination) +{ + return babl_fish_reference_new (source, destination); +} + +void *fooA; +void *fooB; +void *fooC; + +int +babl_fish_process (BablFish *babl_fish, + void *source, + void *destination, + int n) +{ + Babl *babl; + + fooA = malloc(1000); + fooB = malloc(1000); + fooC = malloc(1000); + + assert (source); + assert (destination); + + babl = (Babl *)babl_fish; + if (BABL_IS_BABL (source) || + BABL_IS_BABL (destination)) + { + babl_log ("%s(%p, %p, %p, %i): not handling BablImage yet", + __FUNCTION__, babl_fish, source, destination, n); + return -1; + } + + ((BablConversion*)(babl->reference_fish.type_to_double))->function.linear( + source, + fooA, + n* ((BablPixelFormat*)(babl_fish->source))->bands + ); + /* calculate planar representation of fooA, and fooB */ + /* transform fooA into fooB fooB is rgba double */ + /* calculate planar representation of fooC */ + /* transform fooB into fooC fooC is ???? double */ + + ((BablConversion*)(babl->reference_fish.double_to_type))->function.linear( + fooA, destination, n * ((BablPixelFormat*)(babl_fish->destination))->bands + ); + + return 0; } -BABL_CLASS_TEMPLATE(BablFish, babl_fish, "BablFish") +/*BABL_CLASS_TEMPLATE(BablFish, babl_fish, "BablFish")*/ +BABL_DEFINE_INIT(babl_fish) +BABL_DEFINE_DESTROY(babl_fish) +BABL_DEFINE_EACH(babl_fish) diff --git a/babl/babl-fish.h b/babl/babl-fish.h index 4ed0ada..6e1651e 100644 --- a/babl/babl-fish.h +++ b/babl/babl-fish.h @@ -27,7 +27,11 @@ BABL_DEFINE_CLASS_NO_NEW_NO_ID(BablFish, babl_fish) BablFish * babl_fish_new (Babl *source, Babl *destination); - + +BablFish * +babl_fish (Babl *source, + Babl *destination); + /* babl_fish_process will probably be a polymorph function * accepting source and destination buffer pointers will be * allowed as well as BablImage objects in their place diff --git a/babl/babl-format.c b/babl/babl-format.c index c84536c..8350213 100644 --- a/babl/babl-format.c +++ b/babl/babl-format.c @@ -37,6 +37,7 @@ each_babl_pixel_format_destroy (Babl *babl, babl_free (babl->pixel_format.component); babl_free (babl->pixel_format.type); babl_free (babl->pixel_format.sampling); + babl_free (babl->pixel_format.model); babl_free (babl->instance.name); babl_free (babl); @@ -48,9 +49,10 @@ pixel_format_new (const char *name, int id, int planar, int bands, - BablComponent **band_component, - BablSampling **band_sampling, - BablType **band_type) + BablModel **model, + BablComponent **component, + BablSampling **sampling, + BablType **type) { Babl *self; int band; @@ -64,16 +66,19 @@ pixel_format_new (const char *name, self->pixel_format.bands = bands; self->pixel_format.planar = planar; + self->pixel_format.model = babl_malloc (sizeof (BablModel*) * (bands+1)); self->pixel_format.component = babl_malloc (sizeof (BablComponent*) * (bands+1)); - self->pixel_format.type = babl_malloc (sizeof (BablType*) * (bands+1)); - self->pixel_format.sampling = babl_malloc (sizeof (BablSampling*) * (bands+1)); + self->pixel_format.type = babl_malloc (sizeof (BablType*) * (bands+1)); + self->pixel_format.sampling = babl_malloc (sizeof (BablSampling*) * (bands+1)); for (band=0; band < bands; band++) { - self->pixel_format.component[band] = band_component[band]; - self->pixel_format.type[band] = band_type[band]; - self->pixel_format.sampling[band] = band_sampling[band]; + self->pixel_format.model[band] = model[band]; + self->pixel_format.component[band] = component[band]; + self->pixel_format.type[band] = type[band]; + self->pixel_format.sampling[band] = sampling[band]; } + self->pixel_format.model[band] = NULL; self->pixel_format.component[band] = NULL; self->pixel_format.type[band] = NULL; self->pixel_format.sampling[band] = NULL; @@ -90,13 +95,15 @@ babl_pixel_format_new (const char *name, int id = 0; int planar = 0; int bands = 0; - BablComponent *band_component [BABL_MAX_BANDS]; - BablSampling *band_sampling [BABL_MAX_BANDS]; - BablType *band_type [BABL_MAX_BANDS]; + BablModel *model [BABL_MAX_BANDS]; + BablComponent *component [BABL_MAX_BANDS]; + BablSampling *sampling [BABL_MAX_BANDS]; + BablType *type [BABL_MAX_BANDS]; BablSampling *current_sampling = babl_sampling (1,1); BablType *current_type = babl_type_id (BABL_U8); - const char *arg=name; + BablModel *current_model = NULL; + const char *arg = name; va_start (varg, name); @@ -118,27 +125,31 @@ babl_pixel_format_new (const char *name, current_type = (BablType*) babl; break; case BABL_COMPONENT: - band_component [bands] = (BablComponent*) babl; - band_type [bands] = current_type; - band_sampling [bands] = current_sampling; + if (!current_model) + { + babl_log ("%s(): no model specified before component %s", + __FUNCTION__, babl->instance.name); + } + model [bands] = current_model; + component [bands] = (BablComponent*) babl; + type [bands] = current_type; + sampling [bands] = current_sampling; bands++; if (bands>=BABL_MAX_BANDS) { - babl_log ("maximum number of bands (%i) exceeded for %s", - BABL_MAX_BANDS, name); + babl_log ("%s(): maximum number of bands (%i) exceeded for %s", + __FUNCTION__, BABL_MAX_BANDS, name); } break; case BABL_SAMPLING: current_sampling = (BablSampling*)arg; break; - case BABL_INSTANCE: case BABL_MODEL: - babl_log ("%s(): %s not handled in pixel format yet", - __FUNCTION__, babl_class_name (babl->class_type)); + current_model = (BablModel*)arg; break; + case BABL_INSTANCE: case BABL_PIXEL_FORMAT: - case BABL_CONVERSION: case BABL_CONVERSION_TYPE: case BABL_CONVERSION_TYPE_PLANAR: @@ -182,9 +193,10 @@ babl_pixel_format_new (const char *name, va_end (varg); - self =pixel_format_new (name, id, - planar, - bands, band_component, band_sampling, band_type); + self = pixel_format_new (name, id, + planar, + bands, + model, component, sampling, type); if ((BablPixelFormat*) db_insert ((Babl*)self) == self) diff --git a/babl/babl-instance.h b/babl/babl-instance.h new file mode 100644 index 0000000..3869787 --- /dev/null +++ b/babl/babl-instance.h @@ -0,0 +1,31 @@ +#ifndef _BABL_INSTANCE_H +#define _BABL_INSTANCE_H + +#include "babl-classes.h" +typedef int (*BablEachFunction) (Babl *entry, + void *data); + +const char *babl_class_name (BablClassType klass); + +/* these defines are kept here to keep the typing needed in class + * headers to a minimum, only the ones overriding the basic api with + * custom ways of construction. + */ +#define BABL_DEFINE_CLASS(TypeName, type_name) \ + \ +void type_name##_init (void); \ +void type_name##_destroy (void); \ +void type_name##_each (BablEachFunction each_fun, \ + void *user_data); \ +TypeName * type_name (const char *name); \ +TypeName * type_name##_id (int id); \ +TypeName * type_name##_new (const char *name, \ + ...); +#define BABL_DEFINE_CLASS_NO_NEW_NO_ID(TypeName, type_name) \ + \ +void type_name##_init (void); \ +void type_name##_destroy (void); \ +void type_name##_each (BablEachFunction each_fun, \ + void *user_data); + +#endif diff --git a/babl/babl-internal.h b/babl/babl-internal.h index ea85b82..5426de1 100644 --- a/babl/babl-internal.h +++ b/babl/babl-internal.h @@ -28,6 +28,7 @@ #include "babl-util.h" #include "babl-memory.h" #include "babl-classes.h" +#include "babl-conversion.h" #define babl_log(fmt, args...) do { \ fprintf (stdout, "babl: "); \ @@ -41,7 +42,7 @@ extern int babl_hmpf_on_name_lookups; #define BABL_DEFINE_EACH(type_name) \ void \ type_name##_each (BablEachFunction each_fun, \ - void *user_data) \ + void *user_data) \ { \ db_each (each_fun, user_data); \ } \ diff --git a/babl/babl-pixel-format.c b/babl/babl-pixel-format.c index c84536c..8350213 100644 --- a/babl/babl-pixel-format.c +++ b/babl/babl-pixel-format.c @@ -37,6 +37,7 @@ each_babl_pixel_format_destroy (Babl *babl, babl_free (babl->pixel_format.component); babl_free (babl->pixel_format.type); babl_free (babl->pixel_format.sampling); + babl_free (babl->pixel_format.model); babl_free (babl->instance.name); babl_free (babl); @@ -48,9 +49,10 @@ pixel_format_new (const char *name, int id, int planar, int bands, - BablComponent **band_component, - BablSampling **band_sampling, - BablType **band_type) + BablModel **model, + BablComponent **component, + BablSampling **sampling, + BablType **type) { Babl *self; int band; @@ -64,16 +66,19 @@ pixel_format_new (const char *name, self->pixel_format.bands = bands; self->pixel_format.planar = planar; + self->pixel_format.model = babl_malloc (sizeof (BablModel*) * (bands+1)); self->pixel_format.component = babl_malloc (sizeof (BablComponent*) * (bands+1)); - self->pixel_format.type = babl_malloc (sizeof (BablType*) * (bands+1)); - self->pixel_format.sampling = babl_malloc (sizeof (BablSampling*) * (bands+1)); + self->pixel_format.type = babl_malloc (sizeof (BablType*) * (bands+1)); + self->pixel_format.sampling = babl_malloc (sizeof (BablSampling*) * (bands+1)); for (band=0; band < bands; band++) { - self->pixel_format.component[band] = band_component[band]; - self->pixel_format.type[band] = band_type[band]; - self->pixel_format.sampling[band] = band_sampling[band]; + self->pixel_format.model[band] = model[band]; + self->pixel_format.component[band] = component[band]; + self->pixel_format.type[band] = type[band]; + self->pixel_format.sampling[band] = sampling[band]; } + self->pixel_format.model[band] = NULL; self->pixel_format.component[band] = NULL; self->pixel_format.type[band] = NULL; self->pixel_format.sampling[band] = NULL; @@ -90,13 +95,15 @@ babl_pixel_format_new (const char *name, int id = 0; int planar = 0; int bands = 0; - BablComponent *band_component [BABL_MAX_BANDS]; - BablSampling *band_sampling [BABL_MAX_BANDS]; - BablType *band_type [BABL_MAX_BANDS]; + BablModel *model [BABL_MAX_BANDS]; + BablComponent *component [BABL_MAX_BANDS]; + BablSampling *sampling [BABL_MAX_BANDS]; + BablType *type [BABL_MAX_BANDS]; BablSampling *current_sampling = babl_sampling (1,1); BablType *current_type = babl_type_id (BABL_U8); - const char *arg=name; + BablModel *current_model = NULL; + const char *arg = name; va_start (varg, name); @@ -118,27 +125,31 @@ babl_pixel_format_new (const char *name, current_type = (BablType*) babl; break; case BABL_COMPONENT: - band_component [bands] = (BablComponent*) babl; - band_type [bands] = current_type; - band_sampling [bands] = current_sampling; + if (!current_model) + { + babl_log ("%s(): no model specified before component %s", + __FUNCTION__, babl->instance.name); + } + model [bands] = current_model; + component [bands] = (BablComponent*) babl; + type [bands] = current_type; + sampling [bands] = current_sampling; bands++; if (bands>=BABL_MAX_BANDS) { - babl_log ("maximum number of bands (%i) exceeded for %s", - BABL_MAX_BANDS, name); + babl_log ("%s(): maximum number of bands (%i) exceeded for %s", + __FUNCTION__, BABL_MAX_BANDS, name); } break; case BABL_SAMPLING: current_sampling = (BablSampling*)arg; break; - case BABL_INSTANCE: case BABL_MODEL: - babl_log ("%s(): %s not handled in pixel format yet", - __FUNCTION__, babl_class_name (babl->class_type)); + current_model = (BablModel*)arg; break; + case BABL_INSTANCE: case BABL_PIXEL_FORMAT: - case BABL_CONVERSION: case BABL_CONVERSION_TYPE: case BABL_CONVERSION_TYPE_PLANAR: @@ -182,9 +193,10 @@ babl_pixel_format_new (const char *name, va_end (varg); - self =pixel_format_new (name, id, - planar, - bands, band_component, band_sampling, band_type); + self = pixel_format_new (name, id, + planar, + bands, + model, component, sampling, type); if ((BablPixelFormat*) db_insert ((Babl*)self) == self) diff --git a/babl/babl.c b/babl/babl.c index ab3e96f..a19477f 100644 --- a/babl/babl.c +++ b/babl/babl.c @@ -42,6 +42,7 @@ babl_destroy (void) { /* babl_base is destroy by the containing types */ + babl_fish_destroy (); babl_conversion_destroy (); babl_pixel_format_destroy (); babl_model_destroy (); -- 2.30.2